home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume22 / nn6.4 / part18 < prev    next >
Encoding:
Internet Message Format  |  1990-06-07  |  54.4 KB

  1. Subject:  v22i052:  NN Newsreader, release 6.4, Part18/21
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: c0167a12 57a96eb0 4c755aec 80ad09d7
  5.  
  6. Submitted-by: "Kim F. Storm" <storm@texas.dk>
  7. Posting-number: Volume 22, Issue 52
  8. Archive-name: nn6.4/part18
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then feed it
  12. # into a shell via "sh file" or similar.  To overwrite existing files,
  13. # type "sh file -c".
  14. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  15. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  16. # Contents:  contrib/recmail.c contrib/recmail.sh doc/NEWS-6.3 inst.sh
  17. #   news.c reroute.c unshar.c xmakefile
  18. # Wrapped by storm@texas.dk on Sun May  6 18:20:14 1990
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. echo If this archive is complete, you will see the following message:
  21. echo '          "shar: End of archive 18 (of 22)."'
  22. if test -f 'contrib/recmail.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'contrib/recmail.c'\"
  24. else
  25.   echo shar: Extracting \"'contrib/recmail.c'\" \(7717 characters\)
  26.   sed "s/^X//" >'contrib/recmail.c' <<'END_OF_FILE'
  27. X/*
  28. X *    Copyright (c) 1990 Tom Dawes-Gamble.
  29. X *      For Copyright restrictions see the README file distributed with nn. 
  30. X *          
  31. X *    Mail sender for nn with C news and smail.
  32. X *    
  33. X *      Written by Tom Dawes-Gamble Texas Instruments Ltd, Bedford England.
  34. X *
  35. X *    e-mail tmdg@texins.uucp
  36. X *      uucp   ..!ukc.co.uk!pyrltd!miclon!texins!tmdg
  37. X *
  38. X *      When I installed nn with Cnews I could not find an equivalent
  39. X *    to the Bnews recmail so I wrote this to do the job.
  40. X *    It seems to work for me.
  41. X *    I have no idea how this will work for mailers other than smail
  42. X *
  43. X *    YOU WILL need to look at the way get_host_name works for you system
  44. X *    
  45. X *    If you use this program please let me know so that I can mail you
  46. X *    any enhancements.
  47. X *
  48. X */
  49. X
  50. X/*  you can use the smail defs if required */
  51. X#ifdef SMAIL_DEFS_H
  52. X#include  SMAIL_DEFS_H
  53. X#else
  54. X#define MYDOM ".uucp"
  55. X#endif /* SMAIL_DEFS_H */
  56. X
  57. X#define MAILER "/bin/smail"   /* The pathname of your mailer */
  58. X
  59. X#include <stdio.h>
  60. X#include <errno.h>
  61. X#include <string.h>
  62. X#include <pwd.h>
  63. X#include <sys/utsname.h>
  64. X#include <sys/types.h>
  65. X#include <time.h>
  66. X
  67. X/* where is the local time zone name ? */
  68. X
  69. X    /* xenix 2.3.2 has this in the tm structure */
  70. X/*#define TIMEZONE_NAME(tm) ((tm)->tm_name) /* */
  71. X    /* some systems have it here */
  72. X#define TIMEZONE_NAME(tm) (asctime(tm)?tzname[(tm)->tm_isdst?1:0]:"") /* */
  73. X
  74. Xextern char *getlogin();
  75. Xextern char *getenv();
  76. Xextern char *malloc();
  77. Xextern char *mktemp();
  78. Xextern struct passwd *getpwnam();
  79. Xvoid get_host_name();
  80. X
  81. Xchar *day_name[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  82. X
  83. Xchar *month[] = {    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  84. X            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  85. X
  86. Xchar *mail_template = "/tmp/rmXXXXXX";
  87. Xchar *mail_spool = "/tmp/rmXXXXXX";
  88. X
  89. X#undef BUFSIZ
  90. X#define BUFSIZ 1024          /* a 1024 byte buffer should be enough */
  91. X
  92. X#define ERROR_MSG_0 "%s: Unable to read stdin ** Error = %d\n"
  93. X#define ERROR_MSG_1 "%s: Unable to create spool file ** Error = %d\n"
  94. X
  95. XFILE *sfd, *fopen();
  96. X
  97. Xvoid send_the_message();
  98. Xvoid build_the_header();
  99. X
  100. Xint main(argc, argv)
  101. Xint argc;
  102. Xchar **argv;
  103. X{
  104. X    char inbuff[BUFSIZ];    /*  Buffer for stdin  */
  105. X    char pbuff[BUFSIZ];    /*  Buffer to hold the name of recipients */
  106. X        char **tolist, *tonames[100];  /* I think that should cope for now */ 
  107. X
  108. X    if (argc != 1) {
  109. X        (void) fprintf(stderr,
  110. X            "%s does not allow any arguments yet!\n", argv[0]);
  111. X        exit(1);
  112. X    }
  113. X    tolist = tonames;
  114. X
  115. X/*  FIX  this could be much better */
  116. X    *tolist++ = MAILER;
  117. X    *tolist++ = "-f";
  118. X    *tolist++ = mktemp(strcpy(mail_spool, mail_template));
  119. X    *tolist = pbuff;
  120. X
  121. X    if ((sfd = fopen(mail_spool, "w")) == NULL){
  122. X        (void) fprintf(stderr, ERROR_MSG_1, argv[0], MAILER, errno);
  123. X        exit(1);
  124. X    }
  125. X    build_the_header();
  126. X
  127. X    /* Now send the mail down the tube */
  128. X
  129. X    while((fgets(inbuff, BUFSIZ, stdin)) == inbuff){
  130. X            /* strip blind copies */
  131. X        if (strncmp(inbuff, "Bc: ", 4)){ /* true if not Bc: */
  132. X            (void) fprintf(sfd, "%s", inbuff);
  133. X        }
  134. X         if (!strncmp(inbuff, "To: ", 4)){
  135. X            tolist += get_names(inbuff, tolist);
  136. X        } else if (!strncmp(inbuff, "Cc: ", 4)){
  137. X            tolist += get_names(inbuff, tolist);
  138. X        } else if (!strncmp(inbuff, "Bc: ", 4)){
  139. X            tolist += get_names(inbuff, tolist);
  140. X        } else if (!strcmp(inbuff, "\n")){
  141. X            break;
  142. X        }
  143. X    }
  144. X    while((fgets(inbuff, BUFSIZ, stdin)) == inbuff){
  145. X        (void) fprintf(sfd, "%s", inbuff);
  146. X    }
  147. X    (void) fflush(sfd);
  148. X    (void) fclose(sfd);
  149. X    *tolist = NULL;
  150. X    send_the_message(tonames);
  151. X    exit(0);
  152. X}
  153. X
  154. Xget_names(line_buffer, to_names)
  155. Xchar *line_buffer;
  156. Xchar **to_names;
  157. X{
  158. X    char *curr_name;
  159. X    char *next_name;
  160. X    int name_count;
  161. X
  162. X    name_count = 0;
  163. X    (void) strip_comments(line_buffer);
  164. X        (void) check_for_bracket(line_buffer);
  165. X    while (next_name = strchr(line_buffer, ' ')){
  166. X        *next_name++ = '\0';
  167. X        while (*next_name == ' ')
  168. X            next_name++;
  169. X        curr_name = *to_names;
  170. X        curr_name += strlen(curr_name) + 1;
  171. X        (void) strcpy(*to_names++, line_buffer);
  172. X        *to_names = curr_name;
  173. X        (void) strcpy(line_buffer, next_name);
  174. X        name_count++;
  175. X    }
  176. X    if (strlen(line_buffer)){
  177. X        curr_name = *to_names;
  178. X        curr_name += strlen(curr_name) + 1;
  179. X        (void) strcpy(*to_names++, line_buffer);
  180. X        *to_names = curr_name;
  181. X        name_count++;
  182. X    }
  183. X    return name_count;
  184. X}
  185. X    
  186. X/*    FIX    Correct the order of the head lines */
  187. Xvoid
  188. Xbuild_the_header()
  189. X{
  190. X    struct passwd *login, *getpwnam(), *getpwuid();
  191. X    struct passwd *effective;
  192. X    struct tm *gmt;
  193. X    struct tm *loc;
  194. X    long tics;
  195. X    char hostname[9];
  196. X
  197. X    if(!(login = getpwnam(getlogin())))
  198. X        login = getpwuid(getuid());
  199. X    get_host_name(hostname);
  200. X    gmt = (struct tm *) malloc(sizeof (struct tm));
  201. X    tics = time((long *) 0);
  202. X    loc = gmtime(&tics );
  203. X    *gmt = *loc;
  204. X    loc = localtime(&tics );
  205. X    (void) fprintf(sfd, "%s\n", login->pw_name);
  206. X/* the Reply to: line doesn't look nice on xenix */
  207. X    (void) fprintf(sfd, "Reply-To:   %s@%s%s (%s)\n", login->pw_name,
  208. X        hostname, MYDOM, login->pw_comment);
  209. X/* I'm not sure about this so if it's wrong please tell me */
  210. X    if (getuid() != login->pw_uid){
  211. X        effective = getpwuid(getuid());
  212. X        (void) fprintf(sfd, "Sender:     %s@%s%s (%s)\n", 
  213. X            effective->pw_name, hostname, MYDOM,
  214. X            effective->pw_comment);
  215. X    }
  216. X    (void) fprintf(sfd, "Message-Id: <%d%02d%02d%02d%02d.%s%05d@%s%s>\n", 
  217. X        gmt->tm_year, (gmt->tm_mon + 1), gmt->tm_mday,
  218. X        gmt->tm_hour, gmt->tm_min,
  219. X        "AA", getpid(), hostname, MYDOM);
  220. X    (void) fprintf(sfd, "Date: %s, %d %s %d %02d:%02d:%02d GMT\n", 
  221. X        day_name[gmt->tm_wday], gmt->tm_mday, month[gmt->tm_mon],
  222. X        gmt->tm_year, gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
  223. X    (void) fprintf(sfd, "From: %s@%s%s \(%s\)\n",
  224. X         login->pw_name, hostname, MYDOM, login->pw_comment);
  225. X/*  To help local people know when you sent the mail */
  226. X    if (loc->tm_isdst || strncmp(TIMEZONE_NAME(loc),  "GMT", 3))
  227. X        (void) fprintf(sfd,
  228. X            "X-Local-time: %s, %d %s %d %02d:%02d:%02d %s\n", 
  229. X            day_name[loc->tm_wday], loc->tm_mday,
  230. X            month[loc->tm_mon], loc->tm_year, loc->tm_hour,
  231. X            loc->tm_min, loc->tm_sec, TIMEZONE_NAME(loc));
  232. X}
  233. X
  234. Xvoid
  235. Xsend_the_message(arg_list)
  236. Xchar *arg_list[];
  237. X{
  238. X    int  cid, rid;
  239. X    int  child_stat;
  240. X
  241. X    /*fprintf(stderr, "%s\n", *arg_list);*/
  242. X
  243. X    if (cid = fork()){
  244. X        if ( (rid = wait((int *)&child_stat)) == -1){
  245. X            (void) fprintf(stderr, "%d %d %d %x\n",
  246. X                    cid, rid, errno, child_stat);
  247. X        } else  {
  248. X            cid = 0;
  249. X/* FIX I would like to unlink but can't since it causes smail to fail */
  250. X        /*(void) unlink(mail_spool);*/
  251. X        }
  252. X    } else {
  253. X        (void) execvp(*arg_list, arg_list);
  254. X    }
  255. X    return;
  256. X    
  257. X}
  258. X/* FIX  This is for xenix  System V can use unames */
  259. Xvoid
  260. Xget_host_name(hostname)
  261. Xchar *hostname;
  262. X{
  263. X    FILE *hfd;
  264. X    char *h;
  265. X    
  266. X    hfd = fopen("/etc/systemid", "r");
  267. X    if (hfd == NULL) {
  268. X#ifdef HOSTNAME
  269. X        strcpy(hostname, HOSTNAME);    /* maybe from smail defs.h */
  270. X#else
  271. X        strcpy(hostname, "UNKNOWN");
  272. X#endif
  273. X        return;
  274. X    }
  275. X    h = fgets(hostname, 9, hfd);
  276. X    (void) fclose(hfd);
  277. X    while (*h != '\0')
  278. X        if (*h == '\n')
  279. X            *h = '\0';
  280. X        else
  281. X            h++;
  282. X    return;
  283. X}
  284. X
  285. X/*    remove first word and any comments  */
  286. X/*    Note comment is totaly removed and replaced by space  */
  287. X/*    this may need changeing  */
  288. X/*    all space will be compressed to a single space  */
  289. X/*      FIX required to handle tabs at the moment \tword starting
  290. X    a line will be lost but thats not what I want */
  291. X
  292. Xstrip_comments(buff)
  293. Xchar *buff;
  294. X{
  295. X    char *begin, *end;
  296. X
  297. X    if (end = strchr(buff, ' ')){
  298. X        while (*end == ' ') end++;
  299. X        (void) strcpy(buff, end);
  300. X    }
  301. X    while(begin = strchr(buff, '(')){
  302. X        end = strchr(begin, ')');
  303. X        end++;
  304. X        (void) strcpy(begin, end);
  305. X    }
  306. X    end = strchr(buff, '\n');
  307. X    *end = '\0';
  308. X    return;
  309. X}
  310. X
  311. X
  312. X/*    This routine test the line for <machine readable field>
  313. X        if found then only those fields are left   */
  314. X
  315. Xcheck_for_bracket(buff)
  316. Xchar *buff;
  317. X{
  318. X    char *begin, *end;
  319. X
  320. X    while(begin = strchr(buff, '<')){
  321. X        begin++;
  322. X        (void) strcpy(buff, begin);
  323. X        end = strchr(begin, '>');
  324. X        *end = ' ';
  325. X        buff = end + 1;
  326. X    }
  327. X    return;
  328. X}
  329. END_OF_FILE
  330.   if test 7717 -ne `wc -c <'contrib/recmail.c'`; then
  331.     echo shar: \"'contrib/recmail.c'\" unpacked with wrong size!
  332.   fi
  333.   # end of 'contrib/recmail.c'
  334. fi
  335. if test -f 'contrib/recmail.sh' -a "${1}" != "-c" ; then 
  336.   echo shar: Will not clobber existing file \"'contrib/recmail.sh'\"
  337. else
  338.   echo shar: Extracting \"'contrib/recmail.sh'\" \(1657 characters\)
  339.   sed "s/^X//" >'contrib/recmail.sh' <<'END_OF_FILE'
  340. X#!/bin/sh
  341. X#  This is my version of a mailer that parses the To: lines and invokes the
  342. X#  domain-based mailer        mfr Jul 89
  343. X
  344. Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh $0; kill $$)
  345. X
  346. X# System dependencies
  347. X
  348. Xmailer="/usr/local/smtp"
  349. X# your site name
  350. Xcase undef in
  351. Xdefine) sitename=`hostname` ;;
  352. Xundef) sitename="puppsr" ;;
  353. Xesac
  354. X
  355. Xtest=test
  356. Xsed=/bin/sed
  357. Xecho=/bin/echo
  358. Xcat=/bin/cat
  359. Xgrep=/bin/grep
  360. Xrm=/bin/rm
  361. X
  362. Xdotdir=${DOTDIR-${HOME-$LOGDIR}}
  363. Xtmpart=$dotdir/.letter
  364. X
  365. X    $cat >$tmpart
  366. X
  367. X    case $mailer in
  368. X    *sendmail)
  369. X        $mailer -t <$tmpart
  370. X        ;;
  371. X# but recmail does not know about Bcc, alas
  372. X    *recmail)
  373. X        $mailer <$tmpart
  374. X        ;;
  375. X    *)
  376. X        set X `$sed <$tmpart -n -e '/^To:/{' -e 's/To: *//p' -e q -e '}'`
  377. X        shift
  378. X        set X "$@" `$sed <$tmpart -n -e '/^Cc:/{' -e 's/Cc: *//p' -e q -e '}'`
  379. X        shift
  380. X        set X "$@" `$sed <$tmpart -n -e '/^Bcc:/{' -e 's/Bcc: *//p' -e q -e '}'`
  381. X        shift
  382. X        for i in "$@"
  383. X        do
  384. X        thost=`echo $i | cut -s -d@ -f2`
  385. X        recip=`echo $i | cut -s -d@ -f1`
  386. X        sender=${LOGNAME}@${sitename}
  387. X        $grep -v "^Bcc:"  <$tmpart | $mailer $thost $sender $recip
  388. X        done
  389. X        ;;
  390. X    esac
  391. X    case $? in
  392. X    0)
  393. X        state=cleanup
  394. X        ;;
  395. X    *)
  396. X        state=rescue
  397. X        ;;
  398. X    esac
  399. Xcase $state in
  400. X    rescue)
  401. X    $cat $tmpart >> ${HOME-$LOGDIR}/dead.letter
  402. X    $echo "Message appended to ${HOME-$LOGDIR}/dead.letter"
  403. X    $echo "A copy may be temporarily found in $tmpart"
  404. X    exit
  405. X    ;;
  406. X    cleanup)
  407. X    case "${MAILRECORD-none}" in
  408. X    none)
  409. X        ;;
  410. X    *)  if $cat $tmpart >> $MAILRECORD; then
  411. X        $echo "Article appended to $MAILRECORD"
  412. X        else
  413. X        $echo "Cannot append to $MAILRECORD"
  414. X        fi
  415. X        ;;
  416. X    esac
  417. X    exit
  418. X    ;;
  419. X    esac
  420. Xdone
  421. X
  422. X
  423. END_OF_FILE
  424.   if test 1657 -ne `wc -c <'contrib/recmail.sh'`; then
  425.     echo shar: \"'contrib/recmail.sh'\" unpacked with wrong size!
  426.   fi
  427.   # end of 'contrib/recmail.sh'
  428. fi
  429. if test -f 'doc/NEWS-6.3' -a "${1}" != "-c" ; then 
  430.   echo shar: Will not clobber existing file \"'doc/NEWS-6.3'\"
  431. else
  432.   echo shar: Extracting \"'doc/NEWS-6.3'\" \(6036 characters\)
  433.   sed "s/^X//" >'doc/NEWS-6.3' <<'END_OF_FILE'
  434. XNew features in release 6.3 (compared to release 6.1.5):
  435. X--------------------------------------------------------
  436. X
  437. XMajor improvements:
  438. X    NNTP support
  439. X    nn can now use/update .newsrc (to a limited extent)
  440. X    Presentation of article header can be customized
  441. X    Full macro support
  442. X    Full folder maintenance
  443. X    Completion help available using '?' key
  444. X    Backup of rc file works!
  445. X    Much faster nngoback - not based on history file.
  446. X
  447. XChanges in standard key mappings:
  448. X    reading mode Z -> goto-menu
  449. X    reading mode N -> next-group
  450. X    reading mode p -> previous (was print)
  451. X    reading mode P -> print (was previous)
  452. X
  453. XNew commands:
  454. X    leave-article
  455. X    :define
  456. X    :man
  457. X    :map both ...
  458. X    :patch
  459. X    :pwd
  460. X    :rmail
  461. X    :show groups unsub
  462. X
  463. XNew variables:
  464. X    backup        (New functionality! It is set by default)
  465. X    confirm-append
  466. X    default-save-file
  467. X    delay-redraw
  468. X    header-lines
  469. X    mail
  470. X    mail-format
  471. X    mark-overlap
  472. X    newsrc
  473. X    overlap
  474. X    patch-cmd
  475. X    quick-save
  476. X    retry-on-error
  477. X    save-report
  478. X    word-key
  479. X
  480. XNew options:
  481. X    -m
  482. X    -s/    (regexp matching)
  483. X
  484. XDescription of new features (in mixed order):
  485. X---------------------------------------------
  486. X
  487. XNNTP support has been added (thanks to Rene Seindal @ diku.dk).
  488. X
  489. XOnline manual.
  490. X
  491. XRegular expression search in reading mode:  / and .
  492. X
  493. XRegular expression matching for subjects in -s/ option and G=/ command.
  494. X
  495. XArticles can be saved in a mail compatible format by setting the
  496. Xmail-format variable.
  497. X
  498. XThe article selection save files are now kept in network format if
  499. XNETWORK_DATABASE is defined, so reading news from different machines
  500. Xshould now work in a heterogeneous environment.
  501. X
  502. XAdded $F which expands to the group name with / instead of .  E.g. $F
  503. Xin rec.music.synth produces rec/music/synth
  504. X
  505. XFolder name "+" is expanded to the file name found in the new
  506. Xdefault-save-file variable (default +$F).
  507. X
  508. XWhen saving articles, the prompting for a file name can be disabled by
  509. Xsetting the quick-save variable (saving will be done in the default
  510. Xsave file).
  511. X
  512. Xnn will ask for confirmation before appending to existing files when
  513. Xconfirm-append is set.
  514. X
  515. XThe message after each save can be disabled by unsetting the
  516. Xsave-report variable.
  517. X
  518. XThe manual has been corrected to use the proper names for the
  519. Xmail-record and news-record variables.
  520. X
  521. X:unshar will create the directory if is does not exist.
  522. X
  523. XCustomized article header presentation through setting of header-lines
  524. Xvariable.
  525. X
  526. XComplete variable settings are now shown by :set
  527. X
  528. XFull macro support - you can now bind any sequence of commands to a
  529. Xsingle key (see the define command).
  530. X
  531. XIndividual articles in a folder can now be cancelled!  I.e. folders
  532. Xare now fully supported:  you can save, print, respond to, and cancel
  533. Xseparate articles in the folders created by nn. (Try the G +folder command).
  534. X
  535. XA global init file is now supported rather than just a global sequence file.
  536. X(You should avoid using the sequence file, because it might go away in
  537. Xa future release.)
  538. X
  539. XNn will now remember which articles you have seen on the menu (but not
  540. Xnecessarily selected) when you quit.  Confirming the question "use old
  541. Xselections" now also implies that nn will start on the same menu page
  542. Xas the one you quitted on.
  543. X
  544. XThere is a retry-on-error variable which can be set to a number of
  545. Xtimes attempts to open an article should be done before giving up.
  546. X
  547. XYou can now specify per group default save files in the init file (in
  548. Xthe group sequence).
  549. X
  550. XS+ is an addition to the old S* command which saves all the selected
  551. Xarticles in the group!
  552. X
  553. XWhen you have given a command that clears the screen, the screen is
  554. Xnow redrawn by default when the command terminates.  To get the 6.1
  555. Xbehaviour (prompt for a new : command), you must set the delay-redraw
  556. Xvariable.
  557. X
  558. XWhen input completion is possible, you can now use the ? key to get a
  559. Xlist of the possible completions.
  560. X
  561. XCompletion is now possible when entering an extended command
  562. X(:command) - both for the command name itself and the arguments.
  563. X(The only exception is when entering the VALUE of a variable.)
  564. X
  565. XThe 'backup' variable now works "the right way": It makes a backup of
  566. Xthe rc file on start-up.  nn can then update the rc file after reading
  567. Xeach group (increased security), and still restore the old rc file
  568. Xwith the :q! command.  The backup variable is now set by default.
  569. X
  570. XYou can set the 'mail' variable to make nn check for the arrival of
  571. Xmail, and you can use the ':rmail' command to read the mail!  (But it
  572. Xis not a full mail interface, e.g. you cannot delete messages, cc:
  573. Xfields are not supported if you reply to a message, etc.)
  574. X
  575. Xnn will now synchronize with the .newsrc file if the "newsrc" variable
  576. Xis set.  However, it does NOT understand about individual articles
  577. Xthat are marked as unread (e.g. 5-8 in 1-4,9-24) - it will silently
  578. Xmark such articles as read (e.g. read the above as 1-24).
  579. X  I don't know anybody who uses this, but if somebody wants to improve
  580. Xon it, feel free to do it.  If you just want to to use rn from time to
  581. Xtime, the current support will be sufficient if you always read all
  582. Xthe articles in a group once you have started reading it (or you read
  583. Xthe articles in the normal article number order).
  584. X
  585. XWhen saving an article with a full or partial header in a folder,
  586. Xlegal article header lines in the body of the article are now
  587. Xescaped with a tilde, e.g. ~From: ....., to avoid having the
  588. Xarticles split improperly when the folder is later opened by nn.
  589. X
  590. XThere is a new C)onf command to nnadmin to print the current
  591. Xconfiguration (directories, files, network, etc.).
  592. X
  593. XThe G (goto-group) command now allows you to jump to an unread group
  594. Xin the group sequence without entering a new recursive menu level.
  595. X
  596. XThe manual nn.1 has been clarified regarding the effect of options:
  597. XThe init file is read prior to parsing the options, and the options
  598. Xwill TOGGLE the CURRENT value of boolean variables.
  599. X
  600. X
  601. XRemoved backwards compatibility
  602. X-------------------------------
  603. X
  604. XSupport for upgrading from release 3, 4, or 5 has been removed, since
  605. Xthe sites using these releases have all updated to 6.1.
  606. X
  607. XAlso the support for pre 2.11 news has been removed (OLD_NEWS).
  608. X
  609. END_OF_FILE
  610.   if test 6036 -ne `wc -c <'doc/NEWS-6.3'`; then
  611.     echo shar: \"'doc/NEWS-6.3'\" unpacked with wrong size!
  612.   fi
  613.   # end of 'doc/NEWS-6.3'
  614. fi
  615. if test -f 'inst.sh' -a "${1}" != "-c" ; then 
  616.   echo shar: Will not clobber existing file \"'inst.sh'\"
  617. else
  618.   echo shar: Extracting \"'inst.sh'\" \(7589 characters\)
  619.   sed "s/^X//" >'inst.sh' <<'END_OF_FILE'
  620. X
  621. X# (Large) prefix inserted above by Make
  622. X
  623. X# BSD systems keep chown in /etc
  624. XPATH="$PATH:/etc"
  625. X
  626. Xcase "$1" in
  627. Xmkdir)
  628. X    if [ -n "$2" -a ! -d "$2"/. ]
  629. X    then
  630. X        mkdir $2
  631. X        if [ ! -d "$2" ] ; then
  632. X            echo "Cannot create directory $2"
  633. X            exit 1
  634. X        fi
  635. X        chmod $3 $2
  636. X        chgrp $GROUP $2
  637. X        chown $OWNER $2
  638. X        echo Created directory $2
  639. X    fi
  640. X    exit 0
  641. X    ;;
  642. Xcopy)
  643. X    cp $4 $3
  644. X    chmod $2 $3/$4
  645. X    chgrp $GROUP $3/$4
  646. X    chown $OWNER $3/$4
  647. X    echo "$4 -> $3/$4"
  648. X    exit 0
  649. X    ;;
  650. Xchmod)
  651. X    chmod $2 $3
  652. X    chgrp $GROUP $3
  653. X    chown $OWNER $3
  654. X    exit 0
  655. X    ;;
  656. X
  657. Xinews)
  658. X    if [ ! -d "${INEWS_DIR}"/. ]
  659. X    then
  660. X        ../inst mkdir ${INEWS_DIR} 755 || exit 1
  661. X    fi
  662. X    echo Installing $2 in $INEWS
  663. X    cp $2 $INEWS && ../inst chmod 755 $INEWS
  664. X    exit 0
  665. X    ;;
  666. Xesac
  667. X
  668. Xset -u
  669. X
  670. X(
  671. Xif $NNTP
  672. Xthen
  673. X    :
  674. Xelse
  675. X    if [ ! -d "$SPOOL"/. ]
  676. X    then
  677. X        echo Error: News spool directory $SPOOL not found.
  678. X    fi
  679. X
  680. X    if [ ! -d "$NLIB"/. ]
  681. X    then
  682. X        echo Error: News lib directory $NLIB not found.
  683. X    fi
  684. Xfi
  685. X
  686. Xset $INEWS
  687. Xif [ ! -f "$1" ]
  688. Xthen
  689. X    echo ERROR: Inews program $INEWS not found.
  690. Xfi
  691. X
  692. Xset $RECMAIL
  693. Xif [ ! -f "$1" ]
  694. Xthen
  695. X    echo ERROR: Mailer program $RECMAIL not found.
  696. Xfi
  697. X) > ErrorCheck
  698. X
  699. Xif [ -s ErrorCheck ]
  700. Xthen
  701. X    cat ErrorCheck
  702. X    echo "Hit return to continue"
  703. X    read X
  704. Xfi
  705. Xrm -f ErrorCheck
  706. X
  707. XLOOP=true
  708. Xwhile $LOOP
  709. Xdo
  710. X
  711. Xif [ $# -ge 1 ]
  712. Xthen
  713. X    OPT="$1"
  714. X    shift
  715. X    if [ $# -eq 0 ]
  716. X    then
  717. X        LOOP=false
  718. X    fi
  719. X    PAUSE=false
  720. Xelse
  721. X    PAUSE=true
  722. X
  723. Xecho
  724. Xecho
  725. Xecho "INSTALLATION"
  726. Xecho ""
  727. Xecho "1) Master programs (machine dependent)"
  728. Xecho "2) User programs (machince dependent, shareable)"
  729. Xecho "3) Help files and auxiliary programs (shareable)"
  730. Xecho "4) Documentation (shareable)"
  731. Xecho "5) Online manual (shareable with 3)"
  732. Xecho ""
  733. Xecho "INIT) Initialize database"
  734. Xecho ""
  735. Xecho "s) Server installation:  1 + 2 + 3 + 4 + 5"
  736. Xecho "n) Network installation:     2 + 3 + 4 + 5"
  737. Xecho "m) Master installation:  1"
  738. Xecho "c) Client installation:      2"
  739. Xecho "u) Update after patch"
  740. Xecho "q) Quit"
  741. Xecho ""
  742. Xif ./usercheck 0 ; then
  743. X    :
  744. Xelse
  745. X  echo "Warning: not running as super user"
  746. X  echo ""
  747. Xfi
  748. X${AWK} 'BEGIN{printf "Select option: "}' < /dev/null
  749. Xread OPT
  750. Xecho
  751. X
  752. Xfi
  753. X
  754. Xcase $OPT in
  755. X
  756. Xs*|a*)
  757. X    OPT="master bin aux help online man"
  758. X    ;;
  759. Xu*)
  760. X    OPT=""
  761. X    if [ -f "$MASTER/nnmaster" ]
  762. X    then
  763. X        OPT="$OPT master"
  764. X    fi
  765. X    if [ -f "$BIN/nn" ]
  766. X    then
  767. X        OPT="$OPT bin"
  768. X    fi
  769. X    if [ -f "$LIB/aux" ]
  770. X    then
  771. X        OPT="$OPT aux help"
  772. X    fi
  773. X    if [ -f "$DMAN_DIR/nnmaster.$DMAN_SECT" ]
  774. X    then
  775. X        OPT="$OPT man"
  776. X    fi
  777. X    if [ -f "$HELP/Manual" ]
  778. X    then
  779. X        OPT="$OPT online"
  780. X    fi
  781. X    ;;
  782. X1|m)
  783. X    OPT=master
  784. X    ;;
  785. Xn)
  786. X    OPT="bin aux help online man"
  787. X    ;;
  788. X2|c)
  789. X    OPT=bin
  790. X    ;;
  791. X3)
  792. X    OPT="aux help"
  793. X    ;;
  794. Xx)
  795. X    OPT=aux
  796. X    ;;
  797. Xh)
  798. X    OPT=help
  799. X    ;;
  800. X4)
  801. X    OPT="man"
  802. X    ;;
  803. X5)
  804. X    OPT="online"
  805. X    ;;
  806. XINIT)
  807. X    OPT=init
  808. X    ;;
  809. Xq*|"")
  810. X    if [ -f $MASTER/nnmaster -a ! -f $MASTER/MPID ]
  811. X    then
  812. X        echo "Remember to restart $MASTER/nnmaster"
  813. X    fi
  814. X    exit 0
  815. X    ;;
  816. X*)
  817. X    echo "Unrecognized option: $OPT"
  818. X    exit 1
  819. X    ;;
  820. Xesac
  821. X
  822. Xfor OP in $OPT
  823. Xdo
  824. Xcase "$OP" in
  825. X
  826. Xmaster)
  827. X    ./inst mkdir $MASTER 755 || exit 1
  828. X
  829. X    if [ -f $MASTER/nnmaster ]
  830. X    then
  831. X        (
  832. X        cd $MASTER
  833. X        if [ -f MPID ]
  834. X        then
  835. X            echo "Stopping running master..."
  836. X            kill -1 `cat MPID`
  837. X            sleep 5
  838. X            rm -f MPID
  839. X        fi
  840. X        mv nnmaster nnmaster.old
  841. X       )
  842. X    fi
  843. X
  844. X    echo Installing master in $MASTER
  845. X
  846. X    for prog in $MASTER_PROG
  847. X    do
  848. X        ./inst copy 755 $MASTER $prog
  849. X    done
  850. X
  851. X    chmod 4750 $MASTER/nnmaster
  852. X    ;;
  853. X
  854. Xbin)
  855. X    echo
  856. X    if [ ! -d "$BIN"/. ]
  857. X    then
  858. X        echo Directory $BIN does not found!
  859. X        exit 1
  860. X    fi
  861. X
  862. X    echo Installing user programs in $BIN
  863. X
  864. X    if [ -f $BIN/nn ]
  865. X    then
  866. X         (
  867. X        cd $BIN
  868. X        mv nn nn.old
  869. X        rm -f $BIN_PROG $BIN_LINK
  870. X         )
  871. X    fi
  872. X
  873. X    for prog in $BIN_PROG
  874. X    do
  875. X        ./inst copy 755 $BIN $prog
  876. X    done
  877. X
  878. X    for link in $BIN_LINK
  879. X    do
  880. X        ln $BIN/nn $BIN/$link
  881. X        echo $link linked to nn
  882. X    done
  883. X
  884. X    if [ -f $BIN/nnacct ] ; then
  885. X        chmod 4755 $BIN/nnacct
  886. X        echo nnacct is setuid ${OWNER}.
  887. X    fi
  888. X    ;;
  889. X
  890. Xaux)
  891. X    echo
  892. X    ./inst mkdir $LIB 755 || exit 1
  893. X
  894. X    echo Installing auxiliary programs in $LIB
  895. X
  896. X    for prog in $LIB_PROG
  897. X    do
  898. X        ./inst copy 755 $LIB $prog
  899. X    done
  900. X
  901. X    ./mkprefix conf > ${LIB}/conf
  902. X    grep "^#" config.h |
  903. X    sed -e '/_MAN_/d' -e 's/[     ]*\/\*.*$//' >> ${LIB}/conf
  904. X    ./inst chmod 644 ${LIB}/conf
  905. X    ;;
  906. X
  907. Xhelp)
  908. X    ./inst mkdir $HELP 755 || exit 1
  909. X
  910. X    echo
  911. X    echo Installing help files in $HELP
  912. X
  913. X    for h in `grep '^help/' MANIFEST | sed 's/^help\/\([a-z0-9.]*\).*$/\1/'`
  914. X    do
  915. X        ./cvt-help < help/$h > $HELP/$h
  916. X        ./inst chmod 644 $HELP/$h
  917. X        echo $h
  918. X    done
  919. X    ;;
  920. X
  921. Xman)
  922. X    echo
  923. X    echo Installing manuals
  924. X
  925. X    {
  926. X        echo $UMAN_DIR $UMAN_SECT .1
  927. X        echo $SMAN_DIR $SMAN_SECT .1m
  928. X        echo $DMAN_DIR $DMAN_SECT .8
  929. X    } |
  930. X    while read DIR SECT SRC
  931. X    do
  932. X
  933. X        if [ -d "$DIR"/. -a -w "$DIR"/. ]
  934. X        then
  935. X            for i in man/*$SRC
  936. X            do
  937. X                MAN=`basename ${i} $SRC`
  938. X                NEW=$DIR/${MAN}.$SECT
  939. X                cp $i $NEW
  940. X                ./inst chmod 644 $NEW
  941. X                echo $MAN in $NEW
  942. X            done
  943. X        else
  944. X            echo $DIR not found or not writeable
  945. X        fi
  946. X    done
  947. X    ;;
  948. X
  949. Xonline)
  950. X    ./inst mkdir $HELP 755 || exit 1
  951. X
  952. X    MAN=$HELP/Manual
  953. X
  954. X    echo
  955. X    echo "Formatting online manual $MAN"
  956. X    echo ".... (continues in background) ...."
  957. X
  958. X    rm -f $MAN
  959. X
  960. X    (
  961. X    sed     -e 's/\\f[BPI]//g' \
  962. X        -e 's/\\-/-/g' -e 's/\\&//g' -e 's/\\e/\\/g' \
  963. X        -e '/^\.\\"ta/p' -e '/^\.\\"/d' \
  964. X        -e '/^\.nf/d' -e '/^\.fi/d' \
  965. X        -e '/^\.if/d' -e '/^\.ta/d' -e '/^\.nr/d' \
  966. X        -e '/^\.in/d' -e 's/^\.[BI] //' \
  967. X        `grep '^man/' MANIFEST | ${AWK} '{print $1}'` |
  968. X    ${AWK} -f format.awk - > $MAN
  969. X
  970. X    ./inst chmod 644 $MAN
  971. X    ) &
  972. X    ;;
  973. X
  974. Xinit)
  975. X    echo
  976. X    ./inst mkdir "$DB" 755 || exit 1
  977. X    ./inst mkdir "$DBDATA" 755 || exit 1
  978. X
  979. X    if $NNTP ; then
  980. X        if [ x"$NNTPCACHE" != "x" ] ; then
  981. X            ./inst mkdir "$NNTPCACHE" 777 || exit 1
  982. X        fi    
  983. X        ILIMIT=50
  984. X        DFLT=50
  985. X
  986. X        cat <<'EOF'
  987. X    
  988. XWhen nnmaster is started the first time after initializing nn's
  989. Xdatabase, it will attempt to fetch all the articles from the nntp
  990. Xserver.  It does this by successively requesting each article in the
  991. Xrange min..last obtained from the NNTP server.  Often the 'min' number
  992. Xis unreliable or even zero (Cnews doesn't maintain it).  This means
  993. Xthat the nnmaster will request a lot of non-existing articles from the
  994. Xserver, causing a lot of network traffic.
  995. X
  996. XTo limit this activity, nn will normally only attempt to fetch the
  997. Xfifty newest articles in each group.  This shouldn't really be a
  998. Xproblem since that will give you enough news to start with, and the
  999. Xolder articles will probably be expired in a few days anyway.
  1000. X
  1001. XYou can change this limit if you like.  Or you can disable this
  1002. Xlimitation completely if you trust the min field by giving a 0 limit.
  1003. X
  1004. XEOF
  1005. X    else
  1006. X        ILIMIT=""
  1007. X        DFLT="none"
  1008. X
  1009. X        cat <<'EOF'
  1010. X
  1011. XIf the 'min' field in your active file is not reliable, nnmaster can
  1012. Xwaste a lot of time trying to locate non-existing articles in the news
  1013. Xgroups when it is collecting the available articles the first time it
  1014. Xis started after the database is initialized.  This is especially true
  1015. Xwith Cnews where the min field is not normally maintained.
  1016. X
  1017. XTo limit the efforts during the initial collection, you can set a
  1018. Xlimit on the number of articles in each group which nnmaster should
  1019. Xtry to locate in each group.  This may get you running faster, and it
  1020. Xshouldn't matter much anyway since the articles that may be ignored
  1021. Xwill be the oldest articles in the group, and they will probably be
  1022. Xexpired soon anyway.  A value in the range 100-500 should be more than
  1023. Xenough.  If you don't specify a limit, all articles will be collected,
  1024. Xbut it may take quite some time if the min fields are unreliable.
  1025. XEOF
  1026. X    fi
  1027. X
  1028. X    ${AWK} 'END{printf "Initial article limit ('"$DFLT"') "}' < /dev/null
  1029. X    read L
  1030. X    if [ -n "$L" ] ; then
  1031. X        ILIMIT="$L"
  1032. X    fi
  1033. X
  1034. X    echo Running nnmaster -I $ILIMIT to initialize database....
  1035. X    echo
  1036. X    $MASTER/nnmaster -I $ILIMIT
  1037. X    echo
  1038. X    echo "Now start $MASTER/nnmaster [ -D ] [ -r ]"
  1039. X    ;;
  1040. Xesac
  1041. X
  1042. Xdone
  1043. X
  1044. Xif [ -f $LOG ]
  1045. Xthen
  1046. X    chmod 666 $LOG
  1047. Xfi
  1048. X
  1049. Xif $PAUSE
  1050. Xthen
  1051. X${AWK} 'BEGIN{printf("\nHit return to continue....")}' < /dev/null
  1052. Xread X
  1053. Xfi
  1054. Xdone
  1055. END_OF_FILE
  1056.   if test 7589 -ne `wc -c <'inst.sh'`; then
  1057.     echo shar: \"'inst.sh'\" unpacked with wrong size!
  1058.   fi
  1059.   # end of 'inst.sh'
  1060. fi
  1061. if test -f 'news.c' -a "${1}" != "-c" ; then 
  1062.   echo shar: Will not clobber existing file \"'news.c'\"
  1063. else
  1064.   echo shar: Extracting \"'news.c'\" \(6563 characters\)
  1065.   sed "s/^X//" >'news.c' <<'END_OF_FILE'
  1066. X/*
  1067. X *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  1068. X *
  1069. X *    Article header parsing.
  1070. X */
  1071. X
  1072. X#include "config.h"
  1073. X#include "news.h"
  1074. X
  1075. Xexport retry_on_error = 0;
  1076. X
  1077. Xchar *parse_header(f, hdr_field, modes, hdrbuf)
  1078. XFILE             *f;
  1079. Xchar             **(*hdr_field)();
  1080. Xint             modes;
  1081. Xnews_header_buffer    hdrbuf;
  1082. X{
  1083. X    register char *bp, *cp, **fptr;
  1084. X    int siz, all, date_only;
  1085. X    off_t pos;
  1086. X
  1087. X    pos = ftell(f);
  1088. X
  1089. X/* read first NEWS_HEADER_BUFFER bytes (should be more than enough) */
  1090. X
  1091. X    all     = modes & GET_ALL_FIELDS;
  1092. X    date_only     = modes & GET_DATE_ONLY;
  1093. X
  1094. X    siz = fread(hdrbuf, sizeof(char), NEWS_HEADER_BUFFER, f);
  1095. X
  1096. X    bp = hdrbuf;
  1097. X    bp[siz-1] = NUL;
  1098. X
  1099. X    /* decode subarticle header */
  1100. X    while (*bp) {
  1101. X
  1102. X    if (*bp == NL) {    /* empty line following header */
  1103. X        ++bp;
  1104. X        fseek(f, pos + (bp - hdrbuf), 0);
  1105. X        return bp;
  1106. X    }
  1107. X
  1108. X    if (*bp == SP) {    /* for comp.ai.neural-nets digests */
  1109. X        bp++;        /* which have <NL><space><NL> after header */
  1110. X        continue;
  1111. X    }
  1112. X
  1113. X    if (date_only && *bp != 'D')
  1114. X        fptr = NULL;
  1115. X    else
  1116. X        if (fptr = (*hdr_field)(bp, all)) {
  1117. X        while (*bp && *bp != ':' && isascii(*bp) && !isspace(*bp))
  1118. X            bp++;
  1119. X        bp++;
  1120. X        while (*bp && isascii(*bp) && isspace(*bp) && *bp != NL) bp++;
  1121. X        *fptr = bp;
  1122. X        }
  1123. X
  1124. X    while (*bp && *bp != NL) bp++;
  1125. X
  1126. X    /* Assume that continued lines are never empty! */
  1127. X    if (fptr && bp == *fptr) *fptr = NULL;
  1128. X
  1129. X    while (*bp) {        /* look for continued lines */
  1130. X        cp = bp + 1;
  1131. X        while (*cp && isascii(*cp) && isspace(*cp) && *cp != NL) cp++;
  1132. X
  1133. X        if (cp == bp + 1) {
  1134. X        /* next line is empty or not indented */
  1135. X        *bp++ = NUL;
  1136. X        break;
  1137. X        }
  1138. X
  1139. X        if (*cp == NUL || *cp == NL) {
  1140. X        /* next line is not empty, but blank line */
  1141. X        *bp = NUL;
  1142. X        bp = cp;    /* assume end of header */
  1143. X        break;
  1144. X        }
  1145. X
  1146. X        *bp = SP;        /* substitute NL with SPACE */
  1147. X        bp = cp;
  1148. X        while (*bp && *bp != NL) bp++;
  1149. X    }
  1150. X    }
  1151. X
  1152. X    return bp;
  1153. X}
  1154. X
  1155. Xstatic char **art_hdr_field(lp, all)
  1156. Xregister char *lp;
  1157. Xint all;
  1158. X{
  1159. X
  1160. X#define check(name, lgt, field) \
  1161. X    if (isascii(lp[lgt]) && isspace(lp[lgt]) && strncmp(name, lp, lgt) == 0)\
  1162. X    return &news.field
  1163. X
  1164. X    switch (*lp++) {
  1165. X
  1166. X     case 'A':
  1167. X     case 'a':
  1168. X    if (!all) break;
  1169. X    check("pproved:",     8, ng_appr);
  1170. X    break;
  1171. X
  1172. X     case 'B':
  1173. X     case 'b':
  1174. X    check("ack-References:", 15, ng_bref);
  1175. X    break;
  1176. X
  1177. X     case 'D':
  1178. X     case 'd':
  1179. X    check("ate:",          4, ng_date);
  1180. X    if (!all) break;
  1181. X    check("ate-Received:",    13, ng_rdate);
  1182. X    check("istribution:",     12, ng_dist);
  1183. X    break;
  1184. X
  1185. X     case 'F':
  1186. X     case 'f':
  1187. X    check("rom:",         4, ng_from);
  1188. X    if (!all) break;
  1189. X    check("ollowup-To:",    11, ng_follow);
  1190. X    check("ollowup-to:",    11, ng_follow);
  1191. X    break;
  1192. X
  1193. X     case 'K':
  1194. X     case 'k':
  1195. X    if (!all) break;
  1196. X    check("eywords:",     8, ng_keyw);
  1197. X    break;
  1198. X
  1199. X     case 'L':
  1200. X     case 'l':
  1201. X    check("ines:",          5, ng_xlines);
  1202. X    break;
  1203. X
  1204. X     case 'M':
  1205. X     case 'm':
  1206. X    if (!all) break;
  1207. X    if (strncmp(lp, "essage-", 7)) break;
  1208. X    lp += 7;
  1209. X    check("ID:",    3, ng_ident);
  1210. X    check("Id:",    3, ng_ident);
  1211. X    check("id:",    3, ng_ident);
  1212. X    break;
  1213. X
  1214. X     case 'N':
  1215. X     case 'n':
  1216. X    check("ewsgroups:",    10, ng_groups);
  1217. X    break;
  1218. X
  1219. X     case 'O':
  1220. X     case 'o':
  1221. X    if (!all) break;
  1222. X    check("rganization:",    12, ng_org);
  1223. X    check("rganisation:",    12, ng_org);
  1224. X    break;
  1225. X
  1226. X     case 'P':
  1227. X     case 'p':
  1228. X    if (!all) break;
  1229. X    check("ath:",         4, ng_path);
  1230. X    break;
  1231. X
  1232. X     case 'R':
  1233. X     case 'r':
  1234. X    check("eferences:",    10, ng_ref);
  1235. X    check("eply-To:",     8, ng_reply);
  1236. X    check("eply-to:",     8, ng_reply);
  1237. X    break;
  1238. X
  1239. X     case 'S':
  1240. X     case 's':
  1241. X    check("ubject:",     7, ng_subj);
  1242. X    if (news.ng_from == NULL)
  1243. X        check("ender:",     6, ng_from);
  1244. X    if (!all) break;
  1245. X    check("ummary:",     7, ng_summ);
  1246. X    break;
  1247. X
  1248. X     case 'T':
  1249. X     case 't':
  1250. X    check("itle:",          5, ng_subj);
  1251. X    break;
  1252. X    }
  1253. X
  1254. X    return NULL;
  1255. X
  1256. X#undef check
  1257. X}
  1258. X
  1259. Xis_header_line(line)
  1260. Xchar *line;
  1261. X{
  1262. X    return art_hdr_field(line, 0) != (char **)NULL;
  1263. X}
  1264. X
  1265. X
  1266. XFILE *open_news_article(art, modes, buffer1, buffer2)
  1267. Xarticle_header         *art;
  1268. Xint             modes;
  1269. Xnews_header_buffer    buffer1, buffer2;
  1270. X{
  1271. X    char *body;
  1272. X    char *digest_buffer;
  1273. X    char *parse_header();
  1274. X    struct stat statb;
  1275. X    int retry;
  1276. X    FILE *f;
  1277. X#ifdef NNTP
  1278. X    int lazy;
  1279. X    FILE *nntp_get_article();
  1280. X#endif /* NNTP */
  1281. X
  1282. X    if (art->flag & A_FOLDER) {
  1283. X    f = open_file(group_path_name, OPEN_READ);
  1284. X    if (f == NULL) return NULL;
  1285. X    fseek(f, art->hpos, 0);
  1286. X#ifdef NNTP
  1287. X    } else
  1288. X    if (use_nntp) {
  1289. X    lazy = (current_group->master_flag & M_ALWAYS_DIGEST) == 0
  1290. X        && (modes & LAZY_BODY) ? 1 : 0;
  1291. X    f = nntp_get_article(art->a_number, lazy);
  1292. X    if (f == NULL) return NULL;
  1293. X#endif /* NNTP */
  1294. X    } else {
  1295. X    sprintf(group_file_name, "%d", art->a_number);
  1296. X
  1297. X    retry = retry_on_error;
  1298. X    while ((f = open_file(group_path_name, OPEN_READ)) == NULL)
  1299. X        if (--retry < 0) return NULL;
  1300. X
  1301. X    /* necessary because empty files wreak havoc */
  1302. X    if (fstat(fileno(f), &statb) < 0 ||
  1303. X        statb.st_size < art->lpos || statb.st_size <= (off_t)0) {
  1304. X        fclose(f);
  1305. X        return who_am_i == I_AM_MASTER ? (FILE *)1 : NULL;
  1306. X    }
  1307. X    }
  1308. X
  1309. X    digest_buffer = buffer1;
  1310. X
  1311. X    if (modes & FILL_NEWS_HEADER) {
  1312. X
  1313. X    news.ng_from     = NULL;
  1314. X    news.ng_reply     = NULL;
  1315. X    news.ng_name     = NULL;
  1316. X    news.ng_subj     = NULL;
  1317. X    news.ng_groups     = NULL;
  1318. X    news.ng_ref     = NULL;
  1319. X    news.ng_bref     = NULL;
  1320. X
  1321. X    news.ng_xlines     = NULL;
  1322. X
  1323. X    if (modes & GET_ALL_FIELDS) {
  1324. X        news.ng_path     = NULL;
  1325. X        news.ng_reply     = NULL;
  1326. X        news.ng_ident     = NULL;
  1327. X        news.ng_follow     = NULL;
  1328. X        news.ng_keyw     = NULL;
  1329. X        news.ng_dist     = NULL;
  1330. X        news.ng_org     = NULL;
  1331. X        news.ng_appr     = NULL;
  1332. X        news.ng_summ    = NULL;
  1333. X        news.ng_date    = NULL;
  1334. X        news.ng_rdate    = NULL;
  1335. X    }
  1336. X
  1337. X    if (modes & GET_DATE_ONLY)
  1338. X        news.ng_date    = NULL;
  1339. X
  1340. X    body = parse_header(f, art_hdr_field, modes, buffer1);
  1341. X
  1342. X    news.ng_lines = news.ng_xlines ? atoi(news.ng_xlines) : -1;
  1343. X
  1344. X    if (modes & FILL_OFFSETS) {
  1345. X        art->fpos = news.ng_fpos = ftell(f);
  1346. X
  1347. X        fseek(f, (off_t)0, 2);
  1348. X        news.ng_lpos = ftell(f);
  1349. X    }
  1350. X#ifdef NNTP
  1351. X    else if (use_nntp && (art->flag & A_DIGEST) == 0) {
  1352. X        fseek(f, (off_t)0, 2);
  1353. X        art->lpos = ftell(f);
  1354. X    }
  1355. X#endif
  1356. X
  1357. X    news.ng_flag = 0;
  1358. X
  1359. X    if (news.ng_appr) news.ng_flag |= N_MODERATED;
  1360. X
  1361. X    if (modes & DIGEST_CHECK && is_digest()) news.ng_flag |= N_DIGEST;
  1362. X
  1363. X#ifdef NNTP
  1364. X    if (use_nntp && lazy && news.ng_flag & N_DIGEST) {
  1365. X        fclose(f);
  1366. X        f = nntp_get_article(art->a_number, 2);
  1367. X        if (f == NULL) return NULL;
  1368. X    }
  1369. X#endif
  1370. X    digest_buffer = buffer2;
  1371. X    }
  1372. X#ifdef NNTP
  1373. X    else if (use_nntp && (art->flag & A_DIGEST) == 0) {
  1374. X    fseek(f, (off_t)0, 2);
  1375. X    art->lpos = ftell(f);
  1376. X    }
  1377. X#endif
  1378. X
  1379. X    if (modes & FILL_DIGEST_HEADER) {
  1380. X    fseek(f, art->hpos, 0);
  1381. X    parse_digest_header(f, modes & GET_ALL_FIELDS, digest_buffer);
  1382. X    }
  1383. X
  1384. X    fseek(f, (modes & SKIP_HEADER) ? art->fpos : art->hpos, 0);
  1385. X
  1386. X    return f;
  1387. X}
  1388. END_OF_FILE
  1389.   if test 6563 -ne `wc -c <'news.c'`; then
  1390.     echo shar: \"'news.c'\" unpacked with wrong size!
  1391.   fi
  1392.   # end of 'news.c'
  1393. fi
  1394. if test -f 'reroute.c' -a "${1}" != "-c" ; then 
  1395.   echo shar: Will not clobber existing file \"'reroute.c'\"
  1396. else
  1397.   echo shar: Extracting \"'reroute.c'\" \(7348 characters\)
  1398.   sed "s/^X//" >'reroute.c' <<'END_OF_FILE'
  1399. X/*
  1400. X *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  1401. X *
  1402. X *    Reply address rewriting.
  1403. X */
  1404. X
  1405. X#include "config.h"
  1406. X
  1407. X#define TRACE
  1408. X
  1409. X
  1410. X#ifdef HAVE_ROUTING
  1411. X
  1412. Xreroute(route, address)
  1413. Xchar *route, *address;
  1414. X{
  1415. X    char *name, *atpos;
  1416. X    register char *sp;
  1417. X    register c;
  1418. X
  1419. X    if (atpos = strchr(address, '@')) {
  1420. X    name = atpos;
  1421. X
  1422. X    while (--name >= address)
  1423. X        if (isspace(*name) || *name == '<') {
  1424. X        name++;
  1425. X        break;
  1426. X        }
  1427. X    if (name < address) name++;
  1428. X
  1429. X    for (sp = atpos; c = *sp; sp++)
  1430. X        if (isspace(c) || c == '>') break;
  1431. X
  1432. X    *sp = NUL;
  1433. X    strcpy(route, name);
  1434. X    *sp = c;
  1435. X    } else
  1436. X    strcpy(route, address);
  1437. X    return 1;
  1438. X}
  1439. X
  1440. X#else
  1441. X
  1442. X
  1443. X#ifdef TRACE
  1444. XFILE *route_trace = NULL;
  1445. X#endif
  1446. Xstatic char cmdc;    /* we need this for trace output */
  1447. X
  1448. X
  1449. Xstatic char *cstreq(string, match)
  1450. Xchar *string, *match;
  1451. X{
  1452. X    register char *s1, *s2;
  1453. X    s1 = string;
  1454. X
  1455. Xnext_part:
  1456. X    s2 = match;
  1457. X
  1458. X    while (isspace(*s1) || *s1 == ',') s1++;
  1459. X
  1460. X    while (*s2) {
  1461. X    if (*s1 == NUL || isspace(*s1)) return NULL;
  1462. X    if (*s1 == ',') goto next_part;
  1463. X    if (toupper(*s1) != toupper(*s2)) break;
  1464. X    s1++, s2++;
  1465. X    }
  1466. X
  1467. X    if (*s2 == NUL && (*s1 == NUL || isspace(*s1) || *s1 == ',')) {
  1468. X    if (*s1 == ',') while (*s1 && !isspace(*s1)) s1++;
  1469. X#ifdef TRACE
  1470. X    if (route_trace)
  1471. X        fprintf(route_trace, "/%c %s=%s -> %s", cmdc, string, match, s1);
  1472. X#endif
  1473. X    return s1;
  1474. X    }
  1475. X
  1476. X    while (*s1 && !isspace(*s1)) {
  1477. X    if (*s1 == ',') goto next_part;
  1478. X    s1++;
  1479. X    }
  1480. X
  1481. X    return NULL;
  1482. X}
  1483. X
  1484. X
  1485. Xstatic char *cstrcpy(s1, s2)
  1486. Xregister char *s1, *s2;
  1487. X{
  1488. X    while (*s2 && isspace(*s2)) s2++;
  1489. X    while (*s2 && !isspace(*s2) && *s2 != ',') *s1++ = *s2++;
  1490. X    *s1 = NUL;
  1491. X    return s1;
  1492. X}
  1493. X
  1494. X/*
  1495. X * lookup site,domain in routes database
  1496. X * if not found and bang is non-empty, use bang default if it exist
  1497. X */
  1498. X
  1499. Xstatic find_route(route, remote_user, remote_host, remote_domain, bang)
  1500. Xchar *route, *remote_user, *remote_host, *remote_domain, *bang;
  1501. X{
  1502. X    char line[512];        /* line from route file */
  1503. X    register char *lp;        /* current line position */
  1504. X    char *routep;               /* ptr into route */
  1505. X    char *pattern;        /* pattern from line */
  1506. X    int  dom_ok;        /* in right domain */
  1507. X    int  host_ok;        /* right host */
  1508. X    FILE *rf;            /* route file */
  1509. X    char local_host[100];    /* callers host name */
  1510. X    char local_domain[100];    /* this domain */
  1511. X
  1512. X    if (bang && *bang == NUL) bang = NULL;
  1513. X    if (remote_host == NULL || *remote_host == NUL) return 0;
  1514. X
  1515. X    if (remote_domain && *remote_domain == NUL) remote_domain = NULL;
  1516. X
  1517. X    gethostname(local_host, 100);
  1518. X    if (routep = strchr(local_host, '.')) *routep = NUL;
  1519. X    local_domain[0] = NUL;
  1520. X
  1521. X    rf = open_file(relative(lib_directory, "routes"), OPEN_READ);
  1522. X    if (rf == NULL) {
  1523. X#ifdef TRACE
  1524. X    if (route_trace) fprintf(route_trace, "---No routes file\n");
  1525. X#endif
  1526. X    return 0;
  1527. X    }
  1528. X
  1529. X    dom_ok = host_ok = 1;
  1530. X    routep = route;
  1531. X    pattern = NULL;
  1532. X
  1533. X    while (fgets(line, 512, rf) != NULL) {
  1534. X    lp = line;
  1535. X    while (*lp && isspace(*lp)) lp++;
  1536. X    if (*lp == NUL || *lp == '#') continue;
  1537. X
  1538. X    if (*lp == '/') {
  1539. X        lp++;
  1540. X        cmdc = *lp++;
  1541. X        while (*lp && isspace(*lp)) lp++;
  1542. X        if (*lp == '#') *lp = NUL;
  1543. X
  1544. X        if (cmdc == 'L') {        /* local (default) domain name(s) */
  1545. X        cstrcpy(local_domain, lp);
  1546. X
  1547. X        if (remote_domain == NULL ||
  1548. X            cstreq(lp, remote_domain) != NULL) {
  1549. X            dom_ok = 1;
  1550. X            if (strcmp(local_host, remote_host) == 0) {
  1551. X            pattern = "%p%n";
  1552. X            break;
  1553. X            }
  1554. X        }
  1555. X        continue;
  1556. X        }
  1557. X
  1558. X        if (cmdc == 'D') {        /* destination domain */
  1559. X        if (*lp == NUL)
  1560. X            dom_ok = 1;
  1561. X        else
  1562. X            dom_ok = (cstreq(lp, remote_domain) != NULL);
  1563. X        continue;
  1564. X        }
  1565. X
  1566. X        if (!dom_ok) continue;
  1567. X
  1568. X        if (cmdc == 'H') {        /* local host */
  1569. X        if (*lp == NUL)
  1570. X            host_ok = 1;
  1571. X        else
  1572. X            host_ok = (cstreq(lp, local_host) != NULL);
  1573. X        continue;
  1574. X        }
  1575. X
  1576. X        if (!host_ok) continue;
  1577. X
  1578. X        switch (cmdc) {
  1579. X
  1580. X         case 'N':    /* neighbouring (uucp) sites */
  1581. X        if (cstreq(lp, remote_host) == NULL) continue;
  1582. X        pattern = "%s!%n";
  1583. X        break;
  1584. X
  1585. X         case 'P':
  1586. X        if (*lp == '+')
  1587. X            routep = cstrcpy(routep, ++lp);
  1588. X        else
  1589. X            routep = cstrcpy(route, lp);
  1590. X        continue;
  1591. X
  1592. X         case 'G':
  1593. X        pattern = lp;
  1594. X        break;
  1595. X
  1596. X         case 'B':
  1597. X        if (!bang) continue;
  1598. X        pattern = lp;
  1599. X        break;
  1600. X
  1601. X         default:
  1602. X        continue;
  1603. X        }
  1604. X
  1605. X        break;
  1606. X    }
  1607. X
  1608. X    if (!dom_ok) continue;
  1609. X    if (!host_ok) continue;
  1610. X
  1611. X    if ((pattern = cstreq(lp, remote_host))!=NULL) break;
  1612. X    }
  1613. X
  1614. X    fclose(rf);
  1615. X
  1616. X    if (pattern == NULL) return 0;
  1617. X
  1618. X#ifdef TRACE
  1619. X    if (route_trace) fprintf(route_trace, "   pattern='%s'\n", pattern);
  1620. X#endif
  1621. X
  1622. X    for (; *pattern != NL && *pattern != NUL; pattern++) {
  1623. X    if (*pattern == SP || *pattern == TAB) continue;
  1624. X    if (*pattern == '%') {
  1625. X        pattern++;
  1626. X        switch(*pattern) {
  1627. X         case 'n':
  1628. X        routep = cstrcpy(routep, remote_user);
  1629. X        continue;
  1630. X         case 's':
  1631. X        routep = cstrcpy(routep, remote_host);
  1632. X        continue;
  1633. X         case 'd':
  1634. X        routep = cstrcpy(routep,
  1635. X                 remote_domain ? remote_domain : local_domain);
  1636. X        continue;
  1637. X         case 'b':
  1638. X        routep = cstrcpy(routep, bang);
  1639. X        continue;
  1640. X         case 'p':
  1641. X        routep = route;
  1642. X        continue;
  1643. X         case '%':
  1644. X        break;
  1645. X         default:
  1646. X        continue;
  1647. X        }
  1648. X    }
  1649. X    *routep++ = *pattern;
  1650. X    }
  1651. X    *routep = NUL;
  1652. X
  1653. X    return 1;
  1654. X}
  1655. X
  1656. Xreroute(route, address)
  1657. Xchar *route, *address;
  1658. X{
  1659. X    char *name, *site, *domain;
  1660. X    char *atpos, *dotpos;
  1661. X    register char *sp;
  1662. X    register c;
  1663. X    int found;
  1664. X
  1665. X#ifdef TRACE
  1666. X    if (route_trace ||
  1667. X    (route_trace = open_file(relative(nn_directory, "trace"),
  1668. X                OPEN_APPEND | DONT_CREATE)))
  1669. X    fprintf(route_trace, "--orig: '%s'\n", address);
  1670. X#endif
  1671. X
  1672. X    found = 0;
  1673. X
  1674. X    /* if a sender (or receiver!) is not provided,
  1675. X     * we first try the site from the 'Reply-To:'
  1676. X     * and 'From:' lines  who@site.domain */
  1677. X
  1678. X    if (atpos = strchr(address, '@')) {
  1679. X    *atpos = NUL;
  1680. X    name = atpos;
  1681. X
  1682. X    while (--name >= address)
  1683. X        if (isspace(*name) || *name == '<') {
  1684. X        name++;
  1685. X        break;
  1686. X        }
  1687. X    if (name < address) name++;
  1688. X
  1689. X    dotpos = atpos;
  1690. X    site   = atpos + 1;
  1691. X
  1692. X     next_dot:
  1693. X    *dotpos = NUL;
  1694. X    domain = dotpos + 1;
  1695. X    for (sp = domain; c = *sp; sp++) {
  1696. X        if (isspace(c) || c == '>') break;
  1697. X        if (c == '.') {
  1698. X        *dotpos = '.';
  1699. X        dotpos = sp;
  1700. X        goto next_dot;
  1701. X        }
  1702. X    }
  1703. X    *sp = NUL;
  1704. X    if (site == domain)
  1705. X        domain = NULL;
  1706. X    else
  1707. X        *atpos = NUL;    /* overwritten when first . is found */
  1708. X
  1709. X#ifdef TRACE
  1710. X    if (route_trace)
  1711. X        fprintf(route_trace,
  1712. X            "   @-type: name='%s' site='%s' domain='%s'\n",
  1713. X            name, site, domain ? domain : "");
  1714. X#endif
  1715. X
  1716. X    found = find_route(route, name, site, domain, (char *)NULL);
  1717. X
  1718. X    if (dotpos) { *dotpos = '.'; *sp = c; }
  1719. X    if (atpos) *atpos = '@';
  1720. X
  1721. X    goto out;
  1722. X    }
  1723. X
  1724. X    /*
  1725. X     * not domain address -- look for bang address
  1726. X     */
  1727. X
  1728. X    if (!(name = strrchr(address, '!'))) {
  1729. X    /*
  1730. X     * neither domain nor bang -- suppose it is a local address
  1731. X     */
  1732. X    strcpy(route, address);
  1733. X    found = 1;
  1734. X    goto out;
  1735. X    }
  1736. X
  1737. X    *name++ = NUL;
  1738. X    if (site = strrchr(address, '!'))
  1739. X    *site++ = NUL;
  1740. X    else {
  1741. X    site = address;
  1742. X    address = NULL;
  1743. X    }
  1744. X
  1745. X#ifdef TRACE
  1746. X    if (route_trace)
  1747. X    fprintf(route_trace,
  1748. X        "   !-type: name='%s' site='%s' bang='%s'\n",
  1749. X        name, site, address ? address : "NONE");
  1750. X#endif
  1751. X
  1752. X    found = find_route(route, name, site, (char *)NULL, address);
  1753. X
  1754. X    *--name = '!';
  1755. X    if (address) *--site = '!';
  1756. X
  1757. X out:
  1758. X
  1759. X#ifdef TRACE
  1760. X    if (route_trace) {
  1761. X    if (found)
  1762. X        fprintf(route_trace, "--route='%s'\n\n", route);
  1763. X    else
  1764. X        fprintf(route_trace, "--NO ROUTE\n\n");
  1765. X    fclose(route_trace);
  1766. X    route_trace = NULL;
  1767. X    }
  1768. X#endif
  1769. X    return found;
  1770. X}
  1771. X
  1772. X#endif
  1773. END_OF_FILE
  1774.   if test 7348 -ne `wc -c <'reroute.c'`; then
  1775.     echo shar: \"'reroute.c'\" unpacked with wrong size!
  1776.   fi
  1777.   # end of 'reroute.c'
  1778. fi
  1779. if test -f 'unshar.c' -a "${1}" != "-c" ; then 
  1780.   echo shar: Will not clobber existing file \"'unshar.c'\"
  1781. else
  1782.   echo shar: Extracting \"'unshar.c'\" \(5341 characters\)
  1783.   sed "s/^X//" >'unshar.c' <<'END_OF_FILE'
  1784. X/****************************************************************
  1785. X * unshar.c: Unpackage one or more shell archive files
  1786. X *
  1787. X * Description:    unshar is a filter which removes the front part
  1788. X *        of a file and passes the rest to the 'sh' command.
  1789. X *        It understands phrases like "cut here", and also
  1790. X *        knows about shell comment characters and the Unix
  1791. X *        commands "echo", "cat", and "sed".
  1792. X *
  1793. X * HISTORY
  1794. X *  27-July-88  Kim F. Storm (storm@texas.dk) Texas Instruments, Denmark
  1795. X *    Adapted to :unshar command in nn
  1796. X *    Added static to function declarations
  1797. X *    Removed all unused functions, i.e. not useful as stand-alone pgm.
  1798. X * 29-Jan-85  Michael Mauldin (mlm) at Carnegie-Mellon University
  1799. X *    Created.
  1800. X ****************************************************************/
  1801. X
  1802. X#include "config.h"
  1803. X
  1804. X
  1805. X/*****************************************************************
  1806. X * stlmatch  --  match leftmost part of string
  1807. X *
  1808. X * Usage:  i = stlmatch (big,small)
  1809. X *    int i;
  1810. X *    char *small, *big;
  1811. X *
  1812. X * Returns 1 iff initial characters of big match small exactly;
  1813. X * else 0.
  1814. X *
  1815. X * HISTORY
  1816. X * 18-May-82 Michael Mauldin (mlm) at Carnegie-Mellon University
  1817. X *      Ripped out of CMU lib for Rog-O-Matic portability
  1818. X * 20-Nov-79  Steven Shafer (sas) at Carnegie-Mellon University
  1819. X *    Rewritten for VAX from Ken Greer's routine.
  1820. X *
  1821. X *  Originally from klg (Ken Greer) on IUS/SUS UNIX
  1822. X *****************************************************************/
  1823. X
  1824. Xstatic int   stlmatch (big, small)
  1825. Xchar *small, *big;
  1826. X{ register char *s, *b;
  1827. X  s = small;
  1828. X  b = big;
  1829. X  do
  1830. X  { if (*s == '\0')
  1831. X      return (1);
  1832. X  }
  1833. X  while (*s++ == *b++);
  1834. X  return (0);
  1835. X}
  1836. X
  1837. X/*****************************************************************
  1838. X * smatch: Given a data string and a pattern containing one or
  1839. X * more embedded stars (*) (which match any number of characters)
  1840. X * return true if the match succeeds, and set res[i] to the
  1841. X * characters matched by the 'i'th *.
  1842. X *****************************************************************/
  1843. X
  1844. Xstatic smatch (dat, pat, res)
  1845. Xregister char *dat, *pat, **res;
  1846. X{ register char *star = 0, *starend, *resp;
  1847. X  int nres = 0;
  1848. X
  1849. X  while (1)
  1850. X  { if (*pat == '*')
  1851. X    { star = ++pat;                  /* Pattern after * */
  1852. X      starend = dat;                  /* Data after * match */
  1853. X      resp = res[nres++];              /* Result string */
  1854. X      *resp = '\0';                  /* Initially null */
  1855. X    }
  1856. X    else if (*dat == *pat)              /* Characters match */
  1857. X    { if (*pat == '\0')              /* Pattern matches */
  1858. X    return (1);
  1859. X      pat++;                      /* Try next position */
  1860. X      dat++;
  1861. X    }
  1862. X    else
  1863. X    { if (*dat == '\0')              /* Pattern fails - no more */
  1864. X    return (0);                  /* data */
  1865. X      if (star == 0)                  /* Pattern fails - no * to */
  1866. X    return (0);                  /* adjust */
  1867. X      pat = star;                  /* Restart pattern after * */
  1868. X      *resp++ = *starend;              /* Copy character to result */
  1869. X      *resp = '\0';                  /* null terminate */
  1870. X      dat = ++starend;                  /* Rescan after copied char */
  1871. X    }
  1872. X  }
  1873. X}
  1874. X
  1875. X/****************************************************************
  1876. X * position: position 'fil' at the start of the shell command
  1877. X * portion of a shell archive file.
  1878. X * Kim Storm: removed static variables
  1879. X ****************************************************************/
  1880. X
  1881. Xunshar_position (fil)
  1882. XFILE *fil;
  1883. X{
  1884. X    char buf[BUFSIZ];
  1885. X    long pos, ftell ();
  1886. X
  1887. X    /* Results from star matcher */
  1888. X    char res1[BUFSIZ], res2[BUFSIZ], res3[BUFSIZ], res4[BUFSIZ];
  1889. X    char *result[4];
  1890. X
  1891. X    result[0] = res1, result[1] = res2, result[2] = res3, result[3] = res4 ;
  1892. X
  1893. X    /*  rewind (fil);  */
  1894. X
  1895. X    while (1) {
  1896. X    /* Record position of the start of this line */
  1897. X    pos = ftell (fil);
  1898. X
  1899. X    /* Read next line, fail if no more */
  1900. X    if (fgets (buf, BUFSIZ, fil) == NULL) {
  1901. X        msg("no shell commands in file");
  1902. X        return (0);
  1903. X    }
  1904. X
  1905. X    /* Bail out if we see C preprocessor commands or C comments */
  1906. X    if (stlmatch (buf, "#include")    || stlmatch (buf, "# include") ||
  1907. X        stlmatch (buf, "#define")    || stlmatch (buf, "# define") ||
  1908. X        stlmatch (buf, "#ifdef")    || stlmatch (buf, "# ifdef") ||
  1909. X        stlmatch (buf, "#ifndef")    || stlmatch (buf, "# ifndef") ||
  1910. X        stlmatch (buf, "/*"))
  1911. X        {
  1912. X        msg("file looks like raw C code, not a shar file");
  1913. X        return (0);
  1914. X        }
  1915. X
  1916. X    /* Does this line start with a shell command or comment */
  1917. X    if (stlmatch (buf, "#")    ||
  1918. X        stlmatch (buf, ":") ||
  1919. X        stlmatch (buf, "echo ") ||
  1920. X        stlmatch (buf, "sed ") ||
  1921. X        stlmatch (buf, "cat "))
  1922. X    {
  1923. X        fseek (fil, pos, 0);
  1924. X        return (1);
  1925. X    }
  1926. X
  1927. X    /* Does this line say "Cut here" */
  1928. X    if (smatch (buf, "*CUT*HERE*", result) ||
  1929. X        smatch (buf, "*cut*here*", result) ||
  1930. X        smatch (buf, "*TEAR*HERE*", result) ||
  1931. X        smatch (buf, "*tear*here*", result) ||
  1932. X        smatch (buf, "*CUT*CUT*", result) ||
  1933. X        smatch (buf, "*cut*cut*", result))
  1934. X    {
  1935. X        /* Read next line after "cut here", skipping blank lines */
  1936. X        while (1) {
  1937. X        pos = ftell (fil);
  1938. X
  1939. X        if (fgets (buf, BUFSIZ, fil) == NULL) {
  1940. X            msg("no shell commands after 'cut'");
  1941. X            return (0);
  1942. X        }
  1943. X
  1944. X        if (*buf != '\n') break;
  1945. X        }
  1946. X
  1947. X        /*
  1948. X         * Win if line starts with a comment character of
  1949. X         * lower case letter
  1950. X         */
  1951. X        if (*buf == '#' ||
  1952. X        *buf == ':' ||
  1953. X        (('a' <= *buf) && ('z' >= *buf))) {
  1954. X        fseek (fil, pos, 0);
  1955. X        return (1);
  1956. X        }
  1957. X
  1958. X        /* Cut here message lied to us */
  1959. X        msg("invalid data after CUT line");
  1960. X        return (0);
  1961. X    }
  1962. X    }
  1963. X}
  1964. X
  1965. END_OF_FILE
  1966.   if test 5341 -ne `wc -c <'unshar.c'`; then
  1967.     echo shar: \"'unshar.c'\" unpacked with wrong size!
  1968.   fi
  1969.   # end of 'unshar.c'
  1970. fi
  1971. if test -f 'xmakefile' -a "${1}" != "-c" ; then 
  1972.   echo shar: Will not clobber existing file \"'xmakefile'\"
  1973. else
  1974.   echo shar: Extracting \"'xmakefile'\" \(6903 characters\)
  1975.   sed "s/^X//" >'xmakefile' <<'END_OF_FILE'
  1976. X*
  1977. X* DO NOT CHANGE THIS MAKEFILE DIRECTLY
  1978. X*
  1979. X* THERE ARE NO CONFIGURATION PARAMETERS IN THIS FILE
  1980. X*
  1981. X
  1982. X#include "config.h"
  1983. X#undef global
  1984. X#undef SHELL
  1985. X
  1986. X#ifndef COMPILER_FLAGS
  1987. X#define COMPILER_FLAGS
  1988. X#endif
  1989. X
  1990. X#ifndef EXTRA_LIB
  1991. X#define EXTRA_LIB
  1992. X#endif
  1993. X
  1994. X#ifdef HAVE_ROUTING
  1995. X#define NNMAIL
  1996. X#else
  1997. X#define    NNMAIL nnmail
  1998. X#endif
  1999. X
  2000. X#ifdef ACCOUNTING
  2001. X#define ACCOUNT nnacct
  2002. X#else
  2003. X#ifdef AUTHORIZE
  2004. X#define ACCOUNT nnacct
  2005. X#else
  2006. X#define ACCOUNT
  2007. X#endif
  2008. X#endif
  2009. X------------------ MAKE WILL CUT HERE -------------
  2010. X*
  2011. X* Notice:  ymakefile is made from xmakefile by the Makefile.
  2012. X*
  2013. X
  2014. XCC =     COMPILER
  2015. XCPP =     PREPROC
  2016. XCFLAGS = -Iconf COMPILER_FLAGS CDEBUG
  2017. X
  2018. X*
  2019. X* Resulting programs
  2020. X*
  2021. X
  2022. XBIN_PROG =    nn NNMAIL nnusage nngrab nnstats ACCOUNT
  2023. XBIN_LINK =    nncheck nnadmin nntidy nngoback nngrep nnpost
  2024. XLIB_PROG =    aux upgrade_rc
  2025. XMASTER_PROG =    nnmaster back_act nnspew
  2026. X
  2027. X*
  2028. X* Compilation
  2029. X*
  2030. X
  2031. XSHELL = /bin/sh
  2032. X
  2033. XMASTER = master.o collect.o expire.o proto.o \
  2034. X    global.o options.o active.o db.o nntp.o \
  2035. X    pack_date.o pack_name.o pack_subject.o news.o digest.o
  2036. X
  2037. XNN =     nn.o admin.o proto.o global.o options.o db.o nntp.o \
  2038. X    init.o variable.o term.o keymap.o macro.o regexp.o \
  2039. X    menu.o more.o newsrc.o group.o folder.o dir.o \
  2040. X    sort.o articles.o sequence.o kill.o active.o fullname.o \
  2041. X    answer.o reroute.o hostname.o save.o unshar.o decode.o execute.o \
  2042. X    pack_date.o pack_name.o pack_subject.o news.o digest.o match.o
  2043. X
  2044. XACCT = account.o global.o options.o proto.o
  2045. X
  2046. XMAIL = nnmail.o reroute.o hostname.o global.o options.o
  2047. X
  2048. X
  2049. Xall:    $(BIN_PROG) $(LIB_PROG) $(MASTER_PROG) inst
  2050. X
  2051. Xclient: $(BIN_PROG) $(LIB_PROG) inst
  2052. X
  2053. Xmaster: $(MASTER_PROG) inst
  2054. X
  2055. Xnn:    $(NN)
  2056. X    @echo linking nn
  2057. X    @$(CC) $(CFLAGS) $(NN) TERMLIB EXTRA_LIB -o nn
  2058. X
  2059. Xnnmaster: $(MASTER)
  2060. X    @echo linking nnmaster
  2061. X    @$(CC) $(CFLAGS) $(MASTER) EXTRA_LIB -o nnmaster
  2062. X
  2063. Xnnmail:    $(MAIL)
  2064. X    @echo linking nnmail
  2065. X    @$(CC) $(CFLAGS) $(MAIL) EXTRA_LIB -o nnmail
  2066. X
  2067. Xnnstats: nnstats.sh prefix
  2068. X    cat prefix nnstats.sh > nnstats ; chmod +x nnstats
  2069. X
  2070. Xnnusage: nnusage.sh prefix
  2071. X    cat prefix nnusage.sh > nnusage ; chmod +x nnusage
  2072. X
  2073. Xnngrab:    nngrab.sh prefix
  2074. X    cat prefix nngrab.sh > nngrab ; chmod +x nngrab
  2075. X
  2076. Xaux:     aux.sh prefix
  2077. X    cat prefix aux.sh > aux ; chmod +x aux
  2078. X
  2079. Xupgrade_rc: upgrade_rc.sh prefix
  2080. X    cat prefix upgrade_rc.sh > upgrade_rc ; chmod +x upgrade_rc
  2081. X
  2082. Xnnacct: $(ACCT)
  2083. X    @echo linking nnacct
  2084. X    @$(CC) $(CFLAGS) $(ACCT) EXTRA_LIB -o nnacct
  2085. X
  2086. Xback_act: back_act.sh prefix
  2087. X    cat prefix back_act.sh > back_act ; chmod +x back_act
  2088. X
  2089. Xnnspew:    nnspew.sh prefix
  2090. X    cat prefix nnspew.sh > nnspew ; chmod +x nnspew
  2091. X
  2092. Xprefix:    config.h mkprefix
  2093. X    ./mkprefix prefix < /dev/null > prefix
  2094. X
  2095. Xmkprefix: prefix.o global.o
  2096. X    $(CC) $(CFLAGS) prefix.o global.o EXTRA_LIB -o mkprefix
  2097. X
  2098. X*
  2099. X* Configuration counter updating
  2100. X*
  2101. X
  2102. Xupdate.h:    config.h patchlevel.h Makefile
  2103. X    @sh -c "[ -f update.h ] || (echo 0 > update.h)"
  2104. X    @sh -c "expr `cat update.h` + 1 > update1.h && mv update1.h update.h"
  2105. X    @echo configuration number updated to `cat update.h`
  2106. X
  2107. X*
  2108. X* Installation
  2109. X*
  2110. X
  2111. Xcvt-help:    cvt-help.c
  2112. X    $(CC) -o cvt-help cvt-help.c
  2113. X
  2114. Xusercheck:    usercheck.c
  2115. X    $(CC) -o usercheck usercheck.c
  2116. X
  2117. Xinst: config.h xmakefile inst.sh cvt-help usercheck mkprefix man/nn.1
  2118. X    @echo building install script: ./inst
  2119. X    @./mkprefix full < /dev/null > inst
  2120. X    @echo BIN_PROG=\"$(BIN_PROG)\" >> inst
  2121. X    @echo BIN_LINK=\"$(BIN_LINK)\" >> inst
  2122. X    @echo LIB_PROG=\"$(LIB_PROG)\" >> inst
  2123. X    @echo MASTER_PROG=\"$(MASTER_PROG)\" >> inst
  2124. X    @cat inst.sh >> inst
  2125. X    @chmod 755 inst
  2126. X
  2127. X* merge nn.1
  2128. X
  2129. Xman/nn.1:    man/nn.1.A man/nn.1.B man/nn.1.C man/nn.1.D
  2130. X    [ ! -f man/nn.1 ] || mv man/nn.1 man/nn.1~
  2131. X    cat man/nn.1.? > man/nn.1
  2132. X
  2133. X*
  2134. X* Clean -- remove compiled programs
  2135. X*
  2136. X
  2137. Xclean:
  2138. X    rm -f $(BIN_PROG) $(LIB_PROG) $(MASTER_PROG) cvt-help usercheck
  2139. X
  2140. X*
  2141. X* dependencies
  2142. X*
  2143. X
  2144. Xaccount.o:    account.c config.h global.h vararg.h options.h proto.h
  2145. Xactive.o:    active.c config.h global.h vararg.h data.h
  2146. Xadmin.o:    admin.c config.h global.h vararg.h data.h db.h term.h \
  2147. X        proto.h
  2148. Xanswer.o:    answer.c config.h global.h vararg.h data.h news.h term.h \
  2149. X        keymap.h options.h
  2150. Xarticles.o:    articles.c config.h global.h vararg.h data.h db.h articles.h
  2151. Xcollect.o:    collect.c config.h global.h vararg.h data.h db.h news.h
  2152. Xdb.o:        db.c config.h global.h vararg.h data.h db.h
  2153. Xdecode.o:    decode.c config.h global.h vararg.h data.h
  2154. Xdigest.o:    digest.c config.h global.h vararg.h data.h news.h debug.h
  2155. Xdir.o:        dir.c config.h global.h vararg.h data.h articles.h dir.h
  2156. Xexecute.o:    execute.c config.h global.h vararg.h data.h term.h
  2157. Xexpire.o:    expire.c config.h global.h vararg.h data.h db.h dir.h
  2158. Xfolder.o:    folder.c config.h global.h vararg.h data.h articles.h news.h \
  2159. X        term.h menu.h
  2160. Xfullname.o:    fullname.c config.h global.h
  2161. Xglobal.o:    global.c config.h global.h vararg.h data.h \
  2162. X        patchlevel.h update.h
  2163. Xgroup.o:    group.c config.h global.h vararg.h data.h articles.h db.h \
  2164. X        term.h menu.h keymap.h regexp.h
  2165. Xhostname.o:    hostname.c config.h
  2166. Xinit.o:        init.c config.h global.h vararg.h data.h articles.h term.h \
  2167. X        keymap.h menu.h
  2168. Xkeymap.o:    keymap.c config.h global.h vararg.h data.h keymap.h term.h
  2169. Xkill.o:        kill.c config.h global.h vararg.h data.h term.h regexp.h
  2170. Xmacro.o:    macro.c config.h global.h vararg.h data.h keymap.h term.h
  2171. Xmaster.o:    master.c config.h global.h vararg.h data.h db.h \
  2172. X        options.h proto.h
  2173. Xmatch.o:    match.c config.h global.h regexp.h
  2174. Xmenu.o:        menu.c config.h global.h vararg.h data.h articles.h term.h \
  2175. X        keymap.h menu.h regexp.h
  2176. Xmore.o:        more.c config.h global.h vararg.h data.h news.h term.h \
  2177. X        menu.h keymap.h regexp.h
  2178. Xnews.o:        news.c config.h global.h vararg.h data.h news.h
  2179. Xnn.o:        nn.c config.h global.h vararg.h data.h menu.h term.h \
  2180. X        keymap.h options.h articles.h proto.h
  2181. Xnnmail.o:    nnmail.c config.h global.h vararg.h data.h options.h
  2182. Xnntp.o:        nntp.c config.h global.h vararg.h data.h nntp.h
  2183. Xoptions.o:    options.c config.h global.h vararg.h data.h options.h
  2184. Xpack_date.o:    pack_date.c config.h global.h vararg.h data.h
  2185. Xpack_name.o:    pack_name.c config.h global.h vararg.h data.h
  2186. Xpack_subject.o:    pack_subject.c config.h global.h vararg.h data.h
  2187. Xprefix.o:    config.h global.h
  2188. Xproto.o:    proto.c config.h global.h proto.h
  2189. Xnewsrc.o:    newsrc.c config.h global.h vararg.h data.h term.h debug.h
  2190. Xregexp.o:    regexp.c config.h global.h vararg.h data.h regexp.h
  2191. Xreroute.o:    reroute.c config.h global.h vararg.h data.h
  2192. Xsave.o:        save.c config.h global.h vararg.h data.h term.h keymap.h \
  2193. X        news.h
  2194. Xselection.o:    selection.c config.h global.h vararg.h data.h term.h\
  2195. X         articles.h
  2196. Xsequence.o:    sequence.c config.h global.h vararg.h data.h debug.h
  2197. Xsort.o:        sort.c config.h global.h vararg.h data.h
  2198. Xterm.o:        term.c config.h global.h vararg.h data.h term.h keymap.h
  2199. Xunshar.o:    unshar.c config.h global.h vararg.h data.h
  2200. Xvariable.o:    variable.c config.h global.h vararg.h data.h
  2201. X
  2202. X* link debugging version
  2203. X
  2204. Xnn1:    $(NN)
  2205. X    $(CC) $(CFLAGS) $(NN) TERMLIB EXTRA_LIB -Mnn1 -o nn1
  2206. X
  2207. Xnnmaster1: $(MASTER)
  2208. X    $(CC) $(CFLAGS) $(MASTER) EXTRA_LIB -Mnnmaster1 -o nnmaster1
  2209. X
  2210. Xlint:
  2211. X    echo LINTING NN
  2212. X*    lint -Iconf -u -DNNTP $(NN:.o=.c)
  2213. X    echo LINTING MASTER
  2214. X*    lint -Iconf -u -DNNTP $(MASTER:.o=.c)
  2215. END_OF_FILE
  2216.   if test 6903 -ne `wc -c <'xmakefile'`; then
  2217.     echo shar: \"'xmakefile'\" unpacked with wrong size!
  2218.   fi
  2219.   # end of 'xmakefile'
  2220. fi
  2221. echo shar: End of archive 18 \(of 22\).
  2222. cp /dev/null ark18isdone
  2223. MISSING=""
  2224. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ; do
  2225.     if test ! -f ark${I}isdone ; then
  2226.     MISSING="${MISSING} ${I}"
  2227.     fi
  2228. done
  2229. if test "${MISSING}" = "" ; then
  2230.     echo You have unpacked all 22 archives.
  2231.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2232. else
  2233.     echo You still must unpack the following archives:
  2234.     echo "        " ${MISSING}
  2235. fi
  2236. exit 0
  2237.  
  2238. exit 0 # Just in case...
  2239.